home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / EDITSDI.PAK / SEARCH.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  7KB  |  275 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993-1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE: search.c
  9. //
  10. //  PURPOSE: Implement search and replace on an edit buffer.
  11. //
  12. //  FUNCTIONS:
  13. //    FindReplace- Find and/or replace text in the current document.
  14. //    Find       - Search for a string in the edit text.
  15. //    Replace    - Replace the current selection.
  16. //    ReplaceAll - To replace all of the matches found in the edit text.
  17. //    FWholeWord - Check to see if the match is a whole word.
  18. //
  19. //  COMMENTS:
  20. //
  21.  
  22.  
  23. #include <windows.h>            // required for all Windows applications
  24. #include <ctype.h>
  25. #ifdef WIN16
  26. #include "win16ext.h"           // required only for win16 applications
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #endif
  30. #include "globals.h"            // prototypes specific to this application
  31.  
  32. BOOL Find(char *, BOOL, BOOL, BOOL, BOOL);
  33. VOID Replace(char *);
  34. VOID ReplaceAll(char *, char *, BOOL, BOOL);
  35. BOOL FWholeWord(char *, char *, char *, int);
  36.  
  37. //
  38. //  FUNCTION: FindReplace(char*,char*,BOOL,BOOL,BOOL,BOOL,BOOL,BOOL)
  39. //
  40. //  PURPOSE: Find and/or replace text in the current document.
  41. //
  42. //  PARAMETERS:
  43. //    szFind       - The string to find.
  44. //    szReplace    - The string used to replace.
  45. //    frt -
  46. //      frtFind    - Find the string szFind
  47. //      frtReplace - Replace the current selection with szReplace
  48. //      frtRepAll  - Replace all occurances of szFind with szReplace
  49. //    fDown        - Search down if true, up if false.
  50. //    fMatchCase   - Match case on a search.
  51. //    fWholeWord   - Match whole words only.
  52. //
  53. //  RETURN VALUE:
  54. //    NONE.
  55. //
  56. //  COMMENTS:
  57. //
  58. //
  59.  
  60. VOID FindReplace(
  61.     char *szFind, char *szReplace,
  62.     FRT frt,
  63.     BOOL fDown, BOOL fMatchCase, BOOL fWholeWord)
  64. {
  65.     switch (frt)
  66.     {
  67.         case frtFind:
  68.             Find(szFind, fDown, fMatchCase, fWholeWord, FALSE);
  69.             break;
  70.         case frtReplace:
  71.             Replace(szReplace);
  72.             break;
  73.         case frtRepAll:
  74.             ReplaceAll(szFind, szReplace, fMatchCase, fWholeWord);
  75.     }
  76. }
  77.  
  78.  
  79. //
  80. //  FUNCTION: Find(char *, BOOL, BOOL, BOOL, BOOL)
  81. //
  82. //  PURPOSE: Search for a string in the edit text.
  83. //
  84. //  PARAMETERS:
  85. //    szFind    - The string to search for.
  86. //    fDown     - Search from current position to the end of the text.
  87. //    fMatchCase- Match the case of the search string.
  88. //    fWholeWord- Target must have white space on both sides.
  89. //    fNoScroll - Don't scroll the window to the selection.
  90. //
  91. //  RETURN VALUE:
  92. //    TRUE - String was found.
  93. //    FALSE - Search was not sucessful.
  94. //
  95. //  COMMENTS:
  96. //
  97. //
  98.  
  99. BOOL Find
  100.     (char *szFind, BOOL fDown, BOOL fMatchCase, BOOL fWholeWord, BOOL fNoScroll)
  101. {
  102.     char  *szText;          // Pointer to edit text
  103.     UINT   ichStart;        // Index of start of selection
  104.     UINT   ichEnd;          // Index of end of selection
  105.     UINT   cch;             // Number of charaters in edit text
  106.     int    dch;             // Number of characters to move (+/-1)
  107.     int    dchComp;
  108.     char  *szTerm;          // Pointer to terminal point in search
  109.     char  *sz;              // Pointer to current character
  110.     UINT   cchFind;         // Length of find string
  111.     BOOL   fFound = FALSE;  // Found flag
  112.     int    dchOnFind;       //
  113.  
  114.     szText  = LockEditText(GetEditWindow());
  115.     cchFind = strlen(szFind);
  116.  
  117.     GETSEL(ichStart, ichEnd);
  118.     cch = strlen(szText);
  119.  
  120.     if (
  121.         ichEnd-ichStart == cchFind &&
  122.         !strnicmp(szText+ichStart,szFind,cchFind)
  123.     )
  124.         dchOnFind = 1;
  125.     else
  126.         dchOnFind = 0;
  127.  
  128.     if (fDown)
  129.     {
  130.         dch = 1;
  131.         dchComp = 0;
  132.         sz = szText + ichStart + dchOnFind;
  133.         szTerm = szText + cch;
  134.     }
  135.     else
  136.     {
  137.         dch = -1;
  138.         dchComp = 1;
  139.         sz = szText + ichStart - dchOnFind;
  140.         szTerm = szText;
  141.     }
  142.  
  143.     for (; sz + dchComp != szTerm; sz += dch)
  144.     {
  145.         if (
  146.             tolower(*sz) == tolower(*szFind) &&
  147.             (fMatchCase ?
  148.                 !strncmp(sz,szFind,cchFind) :
  149.                 !strnicmp(sz,szFind,cchFind)
  150.             ) &&
  151.             (!fWholeWord || FWholeWord(sz, szText, szTerm, cchFind)))
  152.         {
  153. #ifdef WIN16
  154.             SendMessage(
  155.                 GetEditWindow(),
  156.                 EM_SETSEL,
  157.                 (WPARAM) fNoScroll,
  158.                 (LPARAM) MAKELONG(sz-szText,sz-szText+cchFind));
  159. #else
  160.             SendMessage(GetEditWindow(), EM_SETSEL, sz-szText, sz-szText+cchFind);
  161.             if (!fNoScroll)
  162.                 SendMessage(GetEditWindow(), EM_SCROLLCARET, 0, 0L);
  163. #endif
  164.             fFound = TRUE;
  165.             break;
  166.         }
  167.     }
  168.  
  169.     if (!fNoScroll && !fFound)
  170.         MessageBox(NULL, szFind, "String not found", MB_OK);
  171.  
  172.     return fFound;
  173. }
  174.  
  175.  
  176. //
  177. //  FUNCTION: Replace(char *)
  178. //
  179. //  PURPOSE: Replace the current selection.
  180. //
  181. //  PARAMETERS:
  182. //    szReplace - The string to replace with.
  183. //
  184. //  RETURN VALUE:
  185. //    NONE
  186. //
  187. //  COMMENTS:
  188. //
  189. //
  190.  
  191. VOID Replace(char *szReplace) {
  192.  
  193.     SendMessage(GetEditWindow(), EM_REPLACESEL, 0, (LPARAM) (LPSTR) szReplace);
  194. }
  195.  
  196. //
  197. //  FUNCTION: ReplaceAll(char *, char *, BOOL, BOOL)
  198. //
  199. //  PURPOSE: To replace all of the matches found in the edit text.
  200. //
  201. //  PARAMETERS:
  202. //    szFind     - The string to replace.
  203. //    szReplace  - The string to replace with.
  204. //    fMatchCase - Replace only exact matches.
  205. //    fWholeWord - Replace only whole word matches.
  206. //
  207. //  RETURN VALUE:
  208. //
  209. //  COMMENTS:
  210. //
  211. //
  212.  
  213. VOID ReplaceAll
  214.     (char *szFind, char *szReplace, BOOL fMatchCase, BOOL fWholeWord)
  215. {
  216.     UINT ichStart;
  217.     UINT ichEnd;
  218.  
  219.     GETSEL(ichStart, ichEnd);
  220.     SETSEL(0,0);
  221.  
  222.     while (Find(szFind, TRUE, fMatchCase, fWholeWord, TRUE)) {
  223.        Replace(szReplace);
  224.     }
  225.  
  226.     SETSEL(ichStart, ichEnd);
  227. }
  228.  
  229.  
  230. //
  231. //  FUNCTION: FWholeWord(char *, char*, char *, int)
  232. //
  233. //  PURPOSE: Check to see if the match is a whole word.
  234. //
  235. //  PARAMETERS:
  236. //    sz     - A pointer to the found string.
  237. //    szStart- A pointer to the beginning of the buffer.
  238. //    szEnd  - A pointer to the end of the buffer.
  239. //    cch    - The lenght of the found string.
  240. //
  241. //  RETURN VALUE:
  242. //    TRUE  - Whole word.
  243. //    FALSE - No a whole word.
  244. //
  245. //  COMMENTS:
  246. //
  247.  
  248. BOOL FWholeWord(char *sz, char *szStart, char *szEnd, int cch) {
  249.     // Is the start of the found text preceded by whitespace?
  250.     if (
  251.         sz != szStart &&
  252.         *(sz-1) != ' ' &&
  253.         *(sz-1) != '\t' &&
  254.         *(sz-1) != ',' &&
  255.         *(sz-1) != '.' &&
  256.         *(sz-1) != '\r'
  257.     ) {
  258.         return FALSE;
  259.     }
  260.  
  261.     // Is the end of the found text followed by whitespace?
  262.     if (
  263.         sz + cch != szEnd &&
  264.         *(sz+cch) != ' ' &&
  265.         *(sz+cch) != '\t' &&
  266.         *(sz+cch) != ',' &&
  267.         *(sz+cch) != '.' &&
  268.         *(sz+cch) != '\r'
  269.     ) {
  270.         return FALSE;
  271.     }
  272.  
  273.     return TRUE;
  274. }
  275.